package com.lw.controller;

import com.lw.dto.Exposer;
import com.lw.dto.SecKillExecution;
import com.lw.dto.SecKillResult;
import com.lw.entity.SecKill;
import com.lw.enums.SecKillStateEnum;
import com.lw.exception.RepeatSecKillException;
import com.lw.exception.SecKillCloseException;
import com.lw.service.SecKillService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;

/**
 * Created by IntelliJ IDEA
 *
 * @Author L1W31
 * @Date 2021/8/5 14:31
 * @Version 1.0
 * @Description
 */
@Controller
@RequestMapping("/secKill")  // url:/模块/资源/{id}/细分
public class SecKillController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private SecKillService secKillService;

    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public String list(Model model) {
        //获取列表页
        List<SecKill> list=secKillService.getSecKillList();
        model.addAttribute("list", list);
        //list.jsp + mode = ModelAndView
        return "list";  // 拼接为：/WEB-INF/jsp/list.jsp
    }

    @RequestMapping(value = "/{secKillId}/detail", method = RequestMethod.GET)
    public String detail(@PathVariable("secKillId") Long secKillId, Model model) {
        // secKillId不存在，重定向到列表页
        if (secKillId == null)
        {
            return "redirect:/secKill/list";
        }

        SecKill secKill=secKillService.getSecKillById(secKillId);

        if (secKill == null)
        {
            return "forward:/secKill/list";
        }

        model.addAttribute("secKill", secKill);

        return "detail";
    }

    //ajax, json暴露秒杀接口的方法
    @RequestMapping(
            value = "/{secKillId}/exposer",
            method = RequestMethod.POST,
            produces = {"application/json;charset=UTF-8"}
            )
    @ResponseBody
    public SecKillResult<Exposer> exposer(@PathVariable("secKillId") Long secKillId) {
        SecKillResult<Exposer> result;
        try {
            Exposer exposer = secKillService.exportSecKillUrl(secKillId);
            result = new SecKillResult<Exposer>(true, exposer);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result = new SecKillResult<Exposer>(false, e.getMessage());
        }

        return result;
    }

    @RequestMapping(
            value = "/{secKillId}/{md5}/execution",
            method = RequestMethod.POST,
            produces = {"application/json;charset=UTF-8"}
            )
    @ResponseBody
    public SecKillResult<SecKillExecution> execute(
            @PathVariable("secKillId") Long secKillId,
            @PathVariable("md5") String md5,
            @CookieValue(value = "killPhone", required = false) Long userPhone) {

        // cookies中没有用户电话
        if (userPhone == null) {
            return new SecKillResult<SecKillExecution>(false, "未注册");
        }

        SecKillResult<SecKillExecution> result;

        try {
            SecKillExecution execution = secKillService.executeSecKill(secKillId, userPhone, md5);
            return new SecKillResult<SecKillExecution>(true, execution);
        } catch (RepeatSecKillException e1) {
            SecKillExecution execution = new SecKillExecution(secKillId, SecKillStateEnum.REPEAT_KILL);
            return new SecKillResult<SecKillExecution>(true, execution);
        } catch (SecKillCloseException e2) {
            SecKillExecution execution = new SecKillExecution(secKillId, SecKillStateEnum.END);
            return new SecKillResult<SecKillExecution>(true, execution);
        } catch (Exception e) {
            SecKillExecution execution = new SecKillExecution(secKillId, SecKillStateEnum.INNER_ERROR);
            return new SecKillResult<SecKillExecution>(true, execution);
        }
    }

    //获取系统时间
    @RequestMapping(value = "/time/now", method = RequestMethod.GET)
    @ResponseBody
    public SecKillResult<Long> time()
    {
        Date now=new Date();
        return new SecKillResult<Long>(true, now.getTime());
    }
}
